package gogo

import (
	"fmt"
	"go2/curl"
	"go2/log"
	"go2/pool"
	"io"
	"os"
	"time"

	"net/http"
	"strings"
	"sync"
)

// 固定URL前缀的钩子结构体
type preMuxEntry struct {
	h       preHttpProcFunc
	pattern string
}

// 固定URL结构体
type staticMuxEntry struct {
	h       HttpProcFunc
	pattern string
}

// 含有":"的智能URL结构体
type imuxEntry struct {
	h         HttpProcFunc
	pattern   string
	urlParams []string
}

// URL转发结构体
type forwardMuxEntry struct {
	target  string
	pattern string
}

func NewHttpRouterHandler() *HttpRouterHandler {
	return &HttpRouterHandler{
		forwardClient: &http.Client{
			Timeout: 30 * time.Second,
			Transport: &http.Transport{
				MaxIdleConns:        100,
				MaxIdleConnsPerHost: 10,
				IdleConnTimeout:     90 * time.Second,
				DisableCompression:  true, // 避免重复压缩
			},
		},
	}
}

// HttpRouterHandler 保存注册函数的地方
type HttpRouterHandler struct {
	mu sync.RWMutex

	//静态路径匹配
	pm map[string]string

	//特殊STATE匹配
	sm map[int]staticMuxEntry

	//固定URL前缀特征匹配，钩子规则
	//map["GET"/"POST"][pattern]staticMuxEntry
	pre_gm map[string]map[string]preMuxEntry

	//固定特征的URL匹配
	//map["GET"/"POST"][pattern]staticMuxEntry
	gm map[string]map[string]staticMuxEntry

	//含有":"的智能URL匹配
	//map["GET"/"POST"][]imuxEntry
	im map[string][]imuxEntry

	//URL转发匹配
	//map["GET"/"POST"][pattern]forwardMuxEntry
	fm map[string]map[string]forwardMuxEntry

	//hosts bool // whether any patterns contain hostnames

	// RegHTTPStatusFunc 注册指定HTTP状态触发的函数
	// status int: HTTP状态, 参考net\http\status.go
	// handler httpProcFunc: 触发函数
	// 全局HTTP客户端，支持连接复用
	forwardClient *http.Client
}

// ServeHTTP 官方HTTP触发入口
func (c *HttpRouterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	log.Debugf("ServeHTTP: %s", r.URL.Path)

	pctx := &HTTPContext{w: w, r: r}

	if c.pre_gm != nil {
		//固定URL前缀特征匹配，钩子规则
		if v, ok := c.pre_gm[r.Method]; ok {
			for prefix, proc := range v {
				if strings.HasPrefix(r.URL.Path, prefix) {
					if !proc.h.PreServeHTTP(pctx) {
						return
					}
				}
			}
		}
	}

	//匹配固定URL规则
	if c.gm != nil {
		if v, ok := c.gm[r.Method][r.URL.Path]; ok {
			v.h.ServeHTTP(pctx)
			return
		}
	}

	//匹配智能URL规则
	if c.im != nil {
		for _, v := range c.im[r.Method] {

			if strings.HasPrefix(r.URL.Path, v.pattern) {
				urlParams := strings.Split(string([]byte(r.URL.Path)[len(v.pattern)+1:]), "/")

				if len(urlParams) == len(v.urlParams) {
					extURLParams := make(map[string]string)
					foundSuss := true

					for urlParamsID, urlParamsValue := range urlParams {

						if strings.HasPrefix(v.urlParams[urlParamsID], ":") {
							extURLParams[v.urlParams[urlParamsID]] = urlParamsValue

						} else if urlParamsValue != v.urlParams[urlParamsID] {
							foundSuss = false
							break
						}
					}

					if foundSuss {
						pctx.urlParams = extURLParams
						v.h.ServeHTTP(pctx)
						return
					}
				}
			}
		}
	}

	//匹配URL转发规则
	if c.fm != nil {
		if v, ok := c.fm[r.Method]; ok {
			for pattern, forward := range v {
				if strings.HasPrefix(r.URL.Path, pattern) {
					// 执行转发
					c.serveHTTPForward(w, r, forward.target+strings.TrimPrefix(r.URL.Path, pattern))
					return
				}
			}
		}
	}

	//匹配静态路径规则
	if c.pm != nil && r.Method == "GET" {
		for pattern, path := range c.pm {
			if strings.HasPrefix(r.URL.Path, pattern) {
				http.ServeFile(w, r, path+strings.TrimPrefix(r.URL.Path, pattern))
				return
			}
		}
	}

	if v, ok := c.sm[http.StatusNotFound]; ok {
		v.h.ServeHTTP(pctx)
	}
}

func (c *HttpRouterHandler) RegHTTPPublic(pattern, path string) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if path == "" {
		panic("http: invalid path")
	}

	if strings.HasSuffix(pattern, "/") {
		pattern = pattern[:len(pattern)-1]
	}
	if strings.HasSuffix(path, "/") {
		path = path[:len(path)-1]
	}

	if c.pm == nil {
		c.pm = make(map[string]string)

	} else {
		// 检查pattern是否之前已经添加过
		if _, exist := c.pm[pattern]; exist {
			panic("http: multiple registrations for " + pattern)
		}
	}

	c.pm[pattern] = path
}

func (c *HttpRouterHandler) RegHTTPPreFunc(method, pattern string, handler preHttpProcFunc) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if handler == nil {
		panic("http: nil handler")
	}

	//检查pattern是否之前已经添加过
	if _, exist := c.pre_gm[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if c.pre_gm == nil {
		c.pre_gm = make(map[string]map[string]preMuxEntry)
	}
	if c.pre_gm[method] == nil {
		c.pre_gm[method] = make(map[string]preMuxEntry)
	}

	c.pre_gm[method][pattern] = preMuxEntry{h: handler, pattern: pattern}
}

// RegHTTPProcFunc 注册固定URL、解析URL函数
// method string: 请求方式，POST、GET、PUT、DELETE等
// pattern string：触发路径
// handler httpProcFunc: 触发函数
func (c *HttpRouterHandler) RegHTTPProcFunc(method, pattern string, handler HttpProcFunc) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if pattern == "" {
		panic("http: invalid pattern")
	}
	if handler == nil {
		panic("http: nil handler")
	}

	//检查pattern是否之前已经添加过
	if _, exist := c.gm[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}
	if _, exist := c.im[pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	if c.gm == nil {
		c.gm = make(map[string]map[string]staticMuxEntry)
	}
	if c.gm[method] == nil {
		c.gm[method] = make(map[string]staticMuxEntry)
	}

	if c.im == nil {
		c.im = make(map[string][]imuxEntry)
	}
	if c.im[method] == nil {
		c.im[method] = []imuxEntry{}
	}

	istart := strings.Index(pattern, "/:")
	if istart == -1 {
		c.gm[method][pattern] = staticMuxEntry{h: handler, pattern: pattern}
	} else {
		if istart <= 1 {
			log.Errorf("%s 错误,请不要以\\:开头!", pattern)
		} else {
			ipattern := string([]byte(pattern)[:istart])
			urlParams := strings.Split(string([]byte(pattern)[istart+1:]), "/")
			c.im[method] = append(c.im[method], imuxEntry{h: handler, urlParams: urlParams, pattern: ipattern})
		}
	}

	/*if pattern[0] != '/' {
		c.hosts = true
	}*/
}

// serveHTTPForward 处理URL转发 - 优化版本支持大数据流式传输
func (c *HttpRouterHandler) serveHTTPForward(w http.ResponseWriter, r *http.Request, targetURL string) {

	if r.URL.RawQuery != "" {
		targetURL = targetURL + "?" + r.URL.RawQuery
	}

	// 创建目标请求
	req, err := http.NewRequest(r.Method, targetURL, r.Body)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Errorf("Error creating request: %v", err)
		return
	}

	// 复制请求头，但排除hop-by-hop头
	for name, values := range r.Header {
		// 跳过hop-by-hop头，这些不应该转发
		if name == "Connection" ||
			name == "Proxy-Connection" ||
			name == "Upgrade" ||
			name == "Proxy-Authenticate" ||
			name == "Proxy-Authorization" ||
			name == "Te" ||
			name == "Trailers" ||
			name == "Transfer-Encoding" {
			continue
		}
		for _, value := range values {
			req.Header.Add(name, value)
		}
	}

	// 使用全局客户端发送请求（支持连接复用）
	resp, err := c.forwardClient.Do(req)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		log.Errorf("Error sending request: %v", err)
		return
	}
	defer resp.Body.Close()

	// 立即复制响应头并发送状态码，启用流式传输
	for name, values := range resp.Header {
		// 跳过hop-by-hop头
		if name == "Connection" ||
			name == "Proxy-Connection" ||
			name == "Upgrade" ||
			name == "Proxy-Authenticate" ||
			name == "Proxy-Authorization" ||
			name == "Te" ||
			name == "Trailers" ||
			name == "Transfer-Encoding" {
			continue
		}
		for _, value := range values {
			w.Header().Add(name, value)
		}
	}

	// 立即设置状态码，开始流式传输
	w.WriteHeader(resp.StatusCode)

	// 检查是否支持Flusher接口（用于流式传输）
	flusher, canFlush := w.(http.Flusher)

	// 使用更大的缓冲区提高大文件传输性能
	buf := pool.Malloc(128 * 1024) // 128KB缓冲区
	defer pool.Free(buf)

	// 流式复制响应体
	var totalBytes int64
	for {
		n, err := resp.Body.Read(buf)
		if n > 0 {
			// 立即写入数据
			written, writeErr := w.Write(buf[:n])
			if writeErr != nil {
				log.Errorf("Error writing response: %v", writeErr)
				return
			}
			totalBytes += int64(written)

			// 如果支持，立即刷新缓冲区
			if canFlush {
				flusher.Flush()
			}
		}
		if err != nil {
			if err == io.EOF {
				break // 正常结束
			}
			log.Errorf("Error reading response body: %v", err)
			return
		}
	}

	log.Debugf("serveHTTPForward: %s, transferred: %d bytes", targetURL, totalBytes)
}

func (c *HttpRouterHandler) serveHTTPForward2(w http.ResponseWriter, r *http.Request, targetURL string) {

	if r.URL.RawQuery != "" {
		targetURL = targetURL + "?" + r.URL.RawQuery
	}

	buf := pool.Malloc(32 * 1024)
	defer pool.Free(buf)

	// 创建HTTP客户端
	client := curl.NewHTTPClient(buf, w)

	body, _ := io.ReadAll(r.Body)

	// 设置请求参数
	req := &curl.Request{
		URL:     targetURL,
		Method:  r.Method,
		Headers: r.Header,
		Data:    body,
	}

	// 发送请求并获取响应
	_, err := client.Do(req)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		os.Exit(1)
	}
}

func (c *HttpRouterHandler) RegHTTPStatusFunc(status int, handler HttpProcFunc) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if status == 0 {
		panic("http: invalid status")
	}
	if handler == nil {
		panic("http: nil handler")
	}

	if c.sm == nil {
		c.sm = make(map[int]staticMuxEntry)
	}

	c.sm[status] = staticMuxEntry{h: handler, pattern: "404"}
}

// RegHTTPForwardWithMethod 注册指定HTTP方法的URL转发规则
// method string: 请求方式，POST、GET、PUT、DELETE等
// pattern string：触发路径
// target string: 目标URL
func (c *HttpRouterHandler) RegHTTPForwardWithMethod(method, pattern, target string) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if method == "" {
		panic("http: invalid method")
	}
	if pattern == "" {
		panic("http: invalid pattern")
	}
	if target == "" {
		panic("http: invalid target")
	}

	if strings.HasSuffix(pattern, "/") {
		pattern = pattern[:len(pattern)-1]
	}
	if strings.HasSuffix(target, "/") {
		target = target[:len(target)-1]
	}

	method = strings.ToUpper(method)

	if c.fm == nil {
		c.fm = make(map[string]map[string]forwardMuxEntry)
	}
	if c.fm[method] == nil {
		c.fm[method] = make(map[string]forwardMuxEntry)
	}

	//检查pattern是否之前已经添加过
	if _, exist := c.fm[method][pattern]; exist {
		panic("http: multiple registrations for " + pattern)
	}

	c.fm[method][pattern] = forwardMuxEntry{target: target, pattern: pattern}
}
